var express = require('express');
var router = express.Router();
var jwt = require('jsonwebtoken');
var { userModel, refreshTokenModel, usersModel } = require('../model/model')



const tencentCloud = require('tencentcloud-sdk-nodejs')//引入腾讯云SDK
const Core = require('@alicloud/pop-core'); // 引入阿里云 SDK


// 注册
router.post('/register', async (req, res) => {
    let { userName, password, phone } = req.body;
    let findResult = await userModel.find({ userName })
    if (findResult.length === 0) {
        await userModel.create({ userName, password, phone })
        res.send({
            code: 200,
            msg: "注册成功"
        })
    } else {
        res.send({
            code: 201,
            msg: "该用户已经注册过，请勿重复注册"
        })
    }
})


// 设置密钥 （最好从环境变量中获取，避免硬代码）
const SECRET_KEY = 'Brave' //确保在生产环境中更改此值
const ACCESS_TOKEN_EXPIRATION = '3s'//访问令牌有效期
const REFRESH_TOKEN_EXPIRATION = '10s'// 刷新令牌有效期
const REFRESH_TOKEN_EXPIRES_IN_MS = 24 * 60 * 60 * 1000// 刷新令牌实际过期时间



//生成函数令牌 refresh
function generateToken(userId, expiration, purpose = 'access') {
    return jwt.sign({ userId, purpose }, SECRET_KEY, { expiresIn: expiration })
}



router.post('/refresh', async (req, res) => {    //刷新短token  刷新令牌
    try {
        const { Refreshtoken } = req.body
        console.log(Refreshtoken);
        let decoded;
        try {
            //判断长token是否过期
            decoded = jwt.verify(Refreshtoken, SECRET_KEY)
            // 判断是不是长token
            if (decoded.purpose != 'refresh') {
                return res.status(301).json({ message: "Invalid token purpose" }) //如果不是长token返回令牌无效
            }
        } catch (_err) {
            return res.status(401).json({ message: "Invalid or expired refresh token" }) //如果token过期或者是无效token 返回401
        }
        // 如果是长token且未过期验证数据库中的令牌
        // 验证数据库中的令牌
        const storeToken = await RefreshTokenModel.findOne({
            token: Refreshtoken,
            expiresAt: { $gt: new Date() }
        })
        if (!storeToken) {
            return res.status(401).json({ message: "Invalid or expired refresh token" })
        }
        const AccssToken = generateToken(decoded.userId, ACCESS_TOKEN_EXPIRATION)
        return res.json({ AccssToken })
    } catch (_err) {
        console.log('Token refres error', _err);
        res.status(500).json({ message: "Internal server error" })
    }

})





//-=========================================>手机登录获取验证码
router.post('/getCode', async (req, res) => {
    let phone = req.body.phone
    try {
        let index = await userModel.findOne({ phone })
        if (index) {
            const client = new Core({                               // 创建 Client 对象
                accessKeyId: 'LTAI5tK2L6XeuDZUGk1P4gpC',           // 替换成自己的 AccessKey ID
                accessKeySecret: 'u3LqvkVkTO9soJsgkb5ESU8MjDOGTU', // 替换成自己的 AccessKey Secret
                endpoint: 'https://dysmsapi.aliyuncs.com',        // API 访问入口，根据实际情况修改
                apiVersion: '2017-05-25'                          // API 版本号，根据实际情况修改
            });
            const code = generateCode();                          // 生成验证码
            const params = {
                "RegionId": "cn-beijing",                      // 短信服务所在区域，可以参考阿里云文档
                "PhoneNumbers": phone,                        // 目标手机号码
                "SignName": "项目专用",                   // 短信签名名称，需先在阿里云控制台中申请审核通过
                "TemplateCode": "SMS_472405009",             // 短信模板 CODE，需先在阿里云控制台中申请审核通过
                "TemplateParam": JSON.stringify({            // 短信模板参数，为 JSON 字符串格式
                    "code": code                              // 模板中的变量名和对应的值
                })
            };
            const requestOption = {   //设置请求超时时间等选项
                method: 'POST',
                timeout: 5000
            }
            // 调用 SendSms 方法发送短信
            client.request('SendSms', params, requestOption).then((result) => {
                console.log(result);
            })
            res.send({ code: 200, infocode: code })
        } else {
            res.send({
                code: 201,
                msg: '手机号格式不正确'
            })
        }
    } catch (error) {
        res.send({ message: "服务器错误", error: error.message })
    }
})

// 短信验证码登录
router.post('/phonelogin', async (req, res) => {
    let { phone } = req.body
    try {
        let info = await userModel.findOne({ phone })
        if (info) {
            let Accesstoken = generateToken(info._id, ACCESS_TOKEN_EXPIRATION)  //短Token
            let Refreshtoken = generateToken(info._id, REFRESH_TOKEN_EXPIRATION)  //长Token
            await refreshTokenModel.create({
                userId: info._id,    //长token关联的外键id
                token: Refreshtoken, //长token
                expireAt: new Date(Date.now() + REFRESH_TOKEN_EXPIRES_IN_MS)  ////长token过期时间
            })

            res.send({
                code: 200,
                info, Accesstoken, Refreshtoken,
                msg: "登录成功",
            })
        } else {
            res.send({
                code: 201,
                msg: "登录失败"
            })
        }
    } catch (error) {
        res.send({ message: '短信登录失败', error: error.message })
    }

})



//人脸登录
router.post('/facelogin', async (req, res) => {
    let { b64 } = req.body
    const IaiClient = tencentCloud.iai.v20200303.Client;
    try {
        const clientConfig = {
            credential: {
                secretId: "AKIDVs2cx5zf6IGzUl0BE8DDH7jDVYO5aru5", //自己的secretId
                secretKey: "94lET5SdaMuEJ9kBTdbM0RfnplbbSCkC",      //密钥
            },
            region: "ap-beijing", //地域参数  (华北地区/北京)
            profile: {
                httpProfile: {
                    endpoint: 'iai.tencentcloudapi.com',
                },
            },
        };
        let cilent = new IaiClient(clientConfig);
        const params = {
            GroupIds: [
                'gyj123456',  //创建的人员库（项目名称）
            ],
            Image: b64,  // 上传的图片为前端传递来的图片
            NeedPersonInfo: 1,  //当认证成功后，是否返回该人员的信息!  默认为0,（0不返回，1返回）
            QualityControl: 0,  //图片质量控制。0为不进行控制，1为较低的质量要求
            FaceMatchThreshold: 85, //对比度大于85才可以认证成功，否则不成功
        }
        let data = await cilent.SearchFaces(params)    //  info为识别成功后返回的信息，可以指定信息返回，最高跟数据库的_id一致
        let _id = data.Results[0].Candidates[0].PersonId
        let info = await userModel.findOne({ _id })
        if (info) {
            let Accesstoken = generateToken(info._id, ACCESS_TOKEN_EXPIRATION)  //短Token
            let Refreshtoken = generateToken(info._id, REFRESH_TOKEN_EXPIRATION)  //长Token
            await refreshTokenModel.create({
                userId: info._id,    //长token关联的外键id
                token: Refreshtoken, //长token
                expireAt: new Date(Date.now() + REFRESH_TOKEN_EXPIRES_IN_MS)  ////长token过期时间
            })
            res.send({
                code: 200,
                Accesstoken, Refreshtoken, info
            })
        } else {
            res.send({
                code: 201
            })
        }

    } catch (err) {
        res.send({
            code: 201
        })
        console.log('err===================>', err);
    }
})


// 生成随机验证码
function generateCode() {
    let code = Math.floor(Math.random() * 9000) + 1000
    return code
}


// 密码登录
router.post('/password', async (req, res) => {
    let { userName, password } = req.body;
    try {
        let result = await usersModel.find({ username: userName })
        if (result) {
            if (result[0].password === password) {
                let Accesstoken = generateToken(result._id, ACCESS_TOKEN_EXPIRATION)  //短Token
                let Refreshtoken = generateToken(result._id, REFRESH_TOKEN_EXPIRATION)  //长Token)
                // console.log(Accesstoken, Refreshtoken, '哈哈哈哈哈哈');
                await refreshTokenModel.create({
                    userId: result._id,    //长token关联的外键id
                    token: Refreshtoken, //长token
                    expireAt: new Date(Date.now() + REFRESH_TOKEN_EXPIRES_IN_MS)  ////长token过期时间
                })
                res.send({
                    code: 200,
                    msg: "登录成功",
                    result, Accesstoken, Refreshtoken
                })
            } else {
                res.send({
                    code: 201,
                    msg: "用户名或密码错误"
                })
            }
        } else {
            res.send({
                code: 203,
                msg: "用户不存在，请先注册"
            })
        }
    } catch (error) {
        res.send({ message: "密码登录错误", error: error.message })
    }

})

// JWT验证中间件
const authenticate = (req, res, next) => {
    const authHeader = req.headers['authorization']
    if (!authHeader || !authHeader.startsWith('Bearer ')) {
        return res.status(401).json({ message: "Missing or invalid authorization header" })
    }
    const token = authHeader.split(' ')[1]
    try {
        const decoded = jwt.verify(token, SECRET_KEY)
        req.user = decoded
        next()
    } catch (error) {
        if (error instanceof jwt.TokenExpiredError) {
            console.log("Token has expired");
            return res.status(401).json({ message: "Token has expired" })
        }
        return res.status(401).json({ message: "Invalid token" })
    }
}


//应用中间件
router.use(authenticate)
router.get('/protectedData', (req, res) => {
    res.json({ message: "Welcome to protected data" })
})



module.exports = router;
